17413
12021
Αυτήν τη στιγμή γράφω έναν βασικό αναλυτή για μια γεύση XML. Ως άσκηση, εφαρμόζω ένα πρόγραμμα ανάλυσης LL που βασίζεται στον πίνακα.
Αυτό είναι το παράδειγμα της γραμματικής BNF:
Συμβολοσειρά δεδομένων% token name
%% / * LL (1) * /
doc: elem
elem: "<" open_tag
open_tag: όνομα attr close_tag
close_tag: ">" elem_or_data ""
| "/>"
;
elem_or_data: "<" open_tag elem_or_data
| δεδομένα elem_or_data
| / * epsilon * /
;
attr: name ":" string attr
| / * epsilon * /
;
Είναι σωστή αυτή η γραμματική;
Κάθε τερματικό κυριολεκτικά είναι μεταξύ εισαγωγικών. Τα αφηρημένα τερματικά καθορίζονται με% token.
Κωδικοποιώ μια χειρόγραφη lexer για να μετατρέψω την είσοδό μου σε μια λίστα διακριτικών. Πώς μπορώ να επισημάνω τα αφηρημένα τερματικά; 
Η κλασική προσέγγιση θα ήταν να γράψετε μια κανονική έκφραση (ή άλλο αναγνωριστικό) για κάθε πιθανό τερματικό.
Αυτό που αποκαλείτε "αφηρημένα" τερματικά, τα οποία είναι απόλυτα συγκεκριμένα, είναι στην πραγματικότητα τερματικά των οποίων τα συσχετισμένα μοτίβα αναγνωρίζουν περισσότερες από μία πιθανές συμβολοσειρές εισόδου. Η συμβολοσειρά που αναγνωρίζεται πραγματικά (ή κάποια υπολογισμένη συνάρτηση αυτής της συμβολοσειράς) πρέπει να μεταβιβάζεται στον αναλυτή ως σημασιολογική τιμή του διακριτικού.
Ονομαστικά, σε κάθε σημείο της συμβολοσειράς εισόδου, το tokeniser θα τρέχει όλους τους αναγνωριστές και θα επιλέξει αυτό με τον μεγαλύτερο αγώνα. (Αυτός είναι ο λεγόμενος κανόνας "μέγιστο munch"). Αυτό μπορεί συνήθως να βελτιστοποιηθεί, ειδικά εάν όλα τα μοτίβα είναι κανονικές εκφράσεις. (F) Η lex θα κάνει αυτήν τη βελτιστοποίηση για εσάς, για παράδειγμα.
Μια περιπλοκή στην περίπτωσή σας είναι ότι η χρήση της γλώσσας σας εξαρτάται από το περιβάλλον. Συγκεκριμένα, όταν ο στόχος είναι elem_or_data, τα μόνα πιθανά διακριτικά είναι <,